Support inline autocompletion in entries (#135953)
authorMatthias Clasen <mclasen@redhat.com>
Mon, 19 Jul 2004 18:15:48 +0000 (18:15 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Mon, 19 Jul 2004 18:15:48 +0000 (18:15 +0000)
2004-07-19  Matthias Clasen  <mclasen@redhat.com>

Support inline autocompletion in entries  (#135953)

* gtk/gtkentryprivate.h:
* gtk/gtkentrycompletion.h:
* gtk/gtkentrycompletion.c (gtk_entry_completion_class_init):
Add a new signal ::insert-prefix which can be used to override
the default inline-completion behaviour. Add two new boolean
properties, :popup_completion and :inline_completion which
determine how the possible completions should be presented.
(gtk_entry_completion_insert_prefix): New function to request
a prefix insertion.

* gtk/gtkentry.c: Add the necessary glue for inline completion.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkentry.c
gtk/gtkentrycompletion.c
gtk/gtkentrycompletion.h
gtk/gtkentryprivate.h

index 84d5109d8b85037fcbd28fd60ea0d860ea91dea6..8498d9225eeeb7a01293469252d4d22503397b3a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2004-07-19  Matthias Clasen  <mclasen@redhat.com>
+
+       Support inline autocompletion in entries  (#135953)
+       
+       * gtk/gtkentryprivate.h: 
+       * gtk/gtkentrycompletion.h: 
+       * gtk/gtkentrycompletion.c (gtk_entry_completion_class_init): 
+       Add a new signal ::insert-prefix which can be used to override 
+       the default inline-completion behaviour. Add two new boolean
+       properties, :popup_completion and :inline_completion which
+       determine how the possible completions should be presented.
+       (gtk_entry_completion_insert_prefix): New function to request
+       a prefix insertion. 
+
+       * gtk/gtkentry.c: Add the necessary glue for inline completion. 
+
 Sun Jul 18 15:28:24 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
 
        * gtk/gtkdnd.c (gtk_drag_source_set, gtk_drag_dest_set): Create an
index 84d5109d8b85037fcbd28fd60ea0d860ea91dea6..8498d9225eeeb7a01293469252d4d22503397b3a 100644 (file)
@@ -1,3 +1,19 @@
+2004-07-19  Matthias Clasen  <mclasen@redhat.com>
+
+       Support inline autocompletion in entries  (#135953)
+       
+       * gtk/gtkentryprivate.h: 
+       * gtk/gtkentrycompletion.h: 
+       * gtk/gtkentrycompletion.c (gtk_entry_completion_class_init): 
+       Add a new signal ::insert-prefix which can be used to override 
+       the default inline-completion behaviour. Add two new boolean
+       properties, :popup_completion and :inline_completion which
+       determine how the possible completions should be presented.
+       (gtk_entry_completion_insert_prefix): New function to request
+       a prefix insertion. 
+
+       * gtk/gtkentry.c: Add the necessary glue for inline completion. 
+
 Sun Jul 18 15:28:24 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
 
        * gtk/gtkdnd.c (gtk_drag_source_set, gtk_drag_dest_set): Create an
index 84d5109d8b85037fcbd28fd60ea0d860ea91dea6..8498d9225eeeb7a01293469252d4d22503397b3a 100644 (file)
@@ -1,3 +1,19 @@
+2004-07-19  Matthias Clasen  <mclasen@redhat.com>
+
+       Support inline autocompletion in entries  (#135953)
+       
+       * gtk/gtkentryprivate.h: 
+       * gtk/gtkentrycompletion.h: 
+       * gtk/gtkentrycompletion.c (gtk_entry_completion_class_init): 
+       Add a new signal ::insert-prefix which can be used to override 
+       the default inline-completion behaviour. Add two new boolean
+       properties, :popup_completion and :inline_completion which
+       determine how the possible completions should be presented.
+       (gtk_entry_completion_insert_prefix): New function to request
+       a prefix insertion. 
+
+       * gtk/gtkentry.c: Add the necessary glue for inline completion. 
+
 Sun Jul 18 15:28:24 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
 
        * gtk/gtkdnd.c (gtk_drag_source_set, gtk_drag_dest_set): Create an
index 84d5109d8b85037fcbd28fd60ea0d860ea91dea6..8498d9225eeeb7a01293469252d4d22503397b3a 100644 (file)
@@ -1,3 +1,19 @@
+2004-07-19  Matthias Clasen  <mclasen@redhat.com>
+
+       Support inline autocompletion in entries  (#135953)
+       
+       * gtk/gtkentryprivate.h: 
+       * gtk/gtkentrycompletion.h: 
+       * gtk/gtkentrycompletion.c (gtk_entry_completion_class_init): 
+       Add a new signal ::insert-prefix which can be used to override 
+       the default inline-completion behaviour. Add two new boolean
+       properties, :popup_completion and :inline_completion which
+       determine how the possible completions should be presented.
+       (gtk_entry_completion_insert_prefix): New function to request
+       a prefix insertion. 
+
+       * gtk/gtkentry.c: Add the necessary glue for inline completion. 
+
 Sun Jul 18 15:28:24 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
 
        * gtk/gtkdnd.c (gtk_drag_source_set, gtk_drag_dest_set): Create an
index fdc658d1647f6b1244cc0a396880e3d791a399d5..9e678ea76bd174297cb6615eead36ffbab8c8e37 100644 (file)
@@ -322,6 +322,31 @@ static void         get_widget_window_size             (GtkEntry       *entry,
                                                        gint           *width,
                                                        gint           *height);
 
+/* Completion */
+static gint         gtk_entry_completion_timeout       (gpointer            data);
+static gboolean     gtk_entry_completion_key_press     (GtkWidget          *widget,
+                                                       GdkEventKey        *event,
+                                                       gpointer            user_data);
+static void         gtk_entry_completion_changed       (GtkWidget          *entry,
+                                                       gpointer            user_data);
+static gboolean     check_completion_callback          (GtkEntryCompletion *completion);
+static void         clear_completion_callback          (GtkEntry           *entry,
+                                                       GParamSpec         *pspec);
+static gboolean     accept_completion_callback         (GtkEntry           *entry);
+static void         completion_insert_text_callback    (GtkEntry           *entry,
+                                                       const gchar        *text,
+                                                       gint                length,
+                                                       gint                position,
+                                                       GtkEntryCompletion *completion);
+static void         completion_changed                 (GtkEntryCompletion *completion,
+                                                       GParamSpec         *pspec,
+                                                       gpointer            data);
+static void         disconnect_completion_signals      (GtkEntry           *entry,
+                                                       GtkEntryCompletion *completion);
+static void         connect_completion_signals         (GtkEntry           *entry,
+                                                       GtkEntryCompletion *completion);
+
+
 static GtkWidgetClass *parent_class = NULL;
 
 GType
@@ -4999,6 +5024,122 @@ gtk_entry_completion_changed (GtkWidget *entry,
                    completion);
 }
 
+static gboolean
+check_completion_callback (GtkEntryCompletion *completion)
+{
+  completion->priv->check_completion_idle = NULL;
+  
+  gtk_entry_completion_insert_prefix (completion);
+
+  return FALSE;
+}
+
+static void
+clear_completion_callback (GtkEntry   *entry,
+                          GParamSpec *pspec)
+{
+  GtkEntryCompletion *completion = gtk_entry_get_completion (entry);
+
+  completion->priv->has_completion = FALSE;
+}
+
+static gboolean
+accept_completion_callback (GtkEntry *entry)
+{
+  GtkEntryCompletion *completion = gtk_entry_get_completion (entry);
+
+  if (completion->priv->has_completion)
+    gtk_editable_set_position (GTK_EDITABLE (entry),
+                              entry->text_length);
+
+  return FALSE;
+}
+
+static void
+completion_insert_text_callback (GtkEntry           *entry,
+                                const gchar        *text,
+                                gint                length,
+                                gint                position,
+                                GtkEntryCompletion *completion)
+{
+  /* idle to update the selection based on the file list */
+  if (completion->priv->check_completion_idle == NULL)
+    {
+      completion->priv->check_completion_idle = g_idle_source_new ();
+      g_source_set_priority (completion->priv->check_completion_idle, G_PRIORITY_HIGH);
+      g_source_set_closure (completion->priv->check_completion_idle,
+                           g_cclosure_new_object (G_CALLBACK (check_completion_callback),
+                                                  G_OBJECT (completion)));
+      g_source_attach (completion->priv->check_completion_idle, NULL);
+    }
+}
+
+static void
+completion_changed (GtkEntryCompletion *completion,
+                   GParamSpec         *pspec,
+                   gpointer            data)
+{
+  GtkEntry *entry = GTK_ENTRY (data);
+
+  disconnect_completion_signals (entry, completion);
+  connect_completion_signals (entry, completion);
+}
+
+static void
+disconnect_completion_signals (GtkEntry           *entry,
+                              GtkEntryCompletion *completion)
+{
+  g_signal_handlers_disconnect_by_func (completion, 
+                                      G_CALLBACK (completion_changed), entry);
+  if (completion->priv->changed_id > 0 &&
+      g_signal_handler_is_connected (entry, completion->priv->changed_id))
+    g_signal_handler_disconnect (entry, completion->priv->changed_id);
+  g_signal_handlers_disconnect_by_func (entry, 
+                                       G_CALLBACK (gtk_entry_completion_key_press), completion);
+  if (completion->priv->insert_text_id > 0 &&
+      g_signal_handler_is_connected (entry, completion->priv->insert_text_id))
+    g_signal_handler_disconnect (entry, completion->priv->insert_text_id);
+  g_signal_handlers_disconnect_by_func (entry, 
+                                       G_CALLBACK (completion_insert_text_callback), completion);
+  g_signal_handlers_disconnect_by_func (entry, 
+                                       G_CALLBACK (clear_completion_callback), completion);
+  g_signal_handlers_disconnect_by_func (entry, 
+                                       G_CALLBACK (accept_completion_callback), completion);
+}
+
+static void
+connect_completion_signals (GtkEntry           *entry,
+                           GtkEntryCompletion *completion)
+{
+  if (completion->priv->popup_completion)
+    {
+      completion->priv->changed_id =
+       g_signal_connect (entry, "changed",
+                         G_CALLBACK (gtk_entry_completion_changed), completion);
+      g_signal_connect (entry, "key_press_event",
+                       G_CALLBACK (gtk_entry_completion_key_press), completion);
+    }
+  if (completion->priv->inline_completion)
+    {
+      completion->priv->insert_text_id =
+       g_signal_connect (entry, "insert_text",
+                         G_CALLBACK (completion_insert_text_callback), completion);
+      g_signal_connect (entry, "notify::cursor-position",
+                       G_CALLBACK (clear_completion_callback), completion);
+      g_signal_connect (entry, "notify::selection-bound",
+                       G_CALLBACK (clear_completion_callback), completion);
+      g_signal_connect (entry, "activate",
+                       G_CALLBACK (accept_completion_callback), completion);
+      g_signal_connect (entry, "focus_out_event",
+                       G_CALLBACK (accept_completion_callback), completion);
+    }
+  g_signal_connect (completion, "notify::popup_completion",
+                   G_CALLBACK (completion_changed), entry);
+  g_signal_connect (completion, "notify::inline_completion",
+                   G_CALLBACK (completion_changed), entry);
+}
+
 /**
  * gtk_entry_set_completion:
  * @entry: A #GtkEntry.
@@ -5035,14 +5176,7 @@ gtk_entry_set_completion (GtkEntry           *entry,
       if (GTK_WIDGET_MAPPED (old->priv->popup_window))
         _gtk_entry_completion_popdown (old);
 
-      gtk_cell_layout_clear (GTK_CELL_LAYOUT (old));
-      old->priv->text_column = -1;
-
-      if (g_signal_handler_is_connected (entry, old->priv->changed_id))
-        g_signal_handler_disconnect (entry, old->priv->changed_id);
-      if (g_signal_handler_is_connected (entry, old->priv->key_press_id))
-        g_signal_handler_disconnect (entry, old->priv->key_press_id);
-
+      disconnect_completion_signals (entry, old);
       old->priv->entry = NULL;
 
       g_object_unref (old);
@@ -5057,14 +5191,7 @@ gtk_entry_set_completion (GtkEntry           *entry,
   /* hook into the entry */
   g_object_ref (completion);
 
-  completion->priv->changed_id =
-    g_signal_connect (entry, "changed",
-                      G_CALLBACK (gtk_entry_completion_changed), completion);
-
-  completion->priv->key_press_id =
-    g_signal_connect (entry, "key_press_event",
-                      G_CALLBACK (gtk_entry_completion_key_press), completion);
-
+  connect_completion_signals (entry, completion);    
   completion->priv->entry = GTK_WIDGET (entry);
   g_object_set_data (G_OBJECT (entry), GTK_ENTRY_COMPLETION_KEY, completion);
 }
index fc86ac324941be8e744ab5346921446c9a9462e5..6743647b53e027e0e5d158d89c421c0d5b1d3632 100644 (file)
@@ -41,6 +41,7 @@
 /* signals */
 enum
 {
+  INSERT_PREFIX,
   MATCH_SELECTED,
   ACTION_ACTIVATED,
   LAST_SIGNAL
@@ -52,7 +53,9 @@ enum
   PROP_0,
   PROP_MODEL,
   PROP_MINIMUM_KEY_LENGTH,
-  PROP_TEXT_COLUMN
+  PROP_TEXT_COLUMN,
+  PROP_INLINE_COMPLETION,
+  PROP_POPUP_COMPLETION
 };
 
 #define GTK_ENTRY_COMPLETION_GET_PRIVATE(obj)(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ENTRY_COMPLETION, GtkEntryCompletionPrivate))
@@ -128,6 +131,8 @@ static void     gtk_entry_completion_action_data_func    (GtkTreeViewColumn
 static gboolean gtk_entry_completion_match_selected      (GtkEntryCompletion *completion,
                                                          GtkTreeModel       *model,
                                                          GtkTreeIter        *iter);
+static gboolean gtk_entry_completion_real_insert_prefix  (GtkEntryCompletion *completion,
+                                                         gchar              *key);
 
 static GObjectClass *parent_class = NULL;
 static guint entry_completion_signals[LAST_SIGNAL] = { 0 };
@@ -185,6 +190,35 @@ gtk_entry_completion_class_init (GtkEntryCompletionClass *klass)
   object_class->finalize = gtk_entry_completion_finalize;
 
   klass->match_selected = gtk_entry_completion_match_selected;
+  klass->insert_prefix = gtk_entry_completion_real_insert_prefix;
+
+  /**
+   * GtkEntryCompletion::insert-prefix:
+   * @widget: the object which received the signal
+   * @prefix: the common prefix of all possible completions
+   * 
+   * The ::insert-prefix signal is emitted when the inline autocompletion
+   * is triggered. The default behaviour is to make the entry display the 
+   * whole prefix and select the newly inserted part.
+   *
+   * Applications may connect to this signal in order to insert only a
+   * smaller part of the @prefix into the entry - e.g. the entry used in
+   * the #GtkFileChooser inserts only the part of the prefix up to the 
+   * next '/'.
+   *
+   * Return value: %TRUE if the signal has been handled
+   * 
+   * Since: 2.6
+   */ 
+  entry_completion_signals[INSERT_PREFIX] =
+    g_signal_new ("insert_prefix",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GtkEntryCompletionClass, insert_prefix),
+                  _gtk_boolean_handled_accumulator, NULL,
+                  _gtk_marshal_BOOLEAN__STRING,
+                  G_TYPE_BOOLEAN, 1,
+                  G_TYPE_STRING);
 
   /**
    * GtkEntryCompletion::match-selected:
@@ -198,6 +232,8 @@ gtk_entry_completion_class_init (GtkEntryCompletionClass *klass)
    * @iter.
    *
    * Return value: %TRUE if the signal has been handled
+   * 
+   * Since: 2.4
    */ 
   entry_completion_signals[MATCH_SELECTED] =
     g_signal_new ("match_selected",
@@ -217,6 +253,8 @@ gtk_entry_completion_class_init (GtkEntryCompletionClass *klass)
    *
    * The ::action-activated signal is emitted when an action
    * is activated.
+   * 
+   * Since: 2.4
    */
   entry_completion_signals[ACTION_ACTIVATED] =
     g_signal_new ("action_activated",
@@ -245,7 +283,7 @@ gtk_entry_completion_class_init (GtkEntryCompletionClass *klass)
                                                      1,
                                                      G_PARAM_READWRITE));
   /**
-   * GtkEntryCompletion::text-column:
+   * GtkEntryCompletion:text-column:
    *
    * The column of the model containing the strings.
    *
@@ -261,6 +299,38 @@ gtk_entry_completion_class_init (GtkEntryCompletionClass *klass)
                                                      -1,
                                                      G_PARAM_READWRITE));
 
+  /**
+   * GtkEntryCompletion:inline_completion:
+   * 
+   * The boolean :inline_completion property determines whether the
+   * common prefix of the possible completions should be inserted 
+   * automatically in the entry.
+   *
+   * Since: 2.6
+   **/
+  g_object_class_install_property (object_class,
+                                  PROP_INLINE_COMPLETION,
+                                  g_param_spec_boolean ("inline_completion",
+                                                        P_("Inline completion"),
+                                                        P_("Whether the common prefix should be inserted automatically"),
+                                                        FALSE,
+                                                        G_PARAM_READWRITE));
+  /**
+   * GtkEntryCompletion:popup_completion:
+   * 
+   * The boolean :popup_completion property determines whether the
+   * possible completions should be shown in a popup window. 
+   *
+   * Since: 2.6
+   **/
+  g_object_class_install_property (object_class,
+                                  PROP_POPUP_COMPLETION,
+                                  g_param_spec_boolean ("popup_completion",
+                                                        P_("Popup completion"),
+                                                        P_("Whether the completions should be shown in a popup window"),
+                                                        TRUE,
+                                                        G_PARAM_READWRITE));
+
   g_type_class_add_private (object_class, sizeof (GtkEntryCompletionPrivate));
 }
 
@@ -289,6 +359,9 @@ gtk_entry_completion_init (GtkEntryCompletion *completion)
 
   priv->minimum_key_length = 1;
   priv->text_column = -1;
+  priv->has_completion = FALSE;
+  priv->inline_completion = FALSE;
+  priv->popup_completion = TRUE;
 
   /* completions */
   priv->filter_model = NULL;
@@ -410,6 +483,14 @@ gtk_entry_completion_set_property (GObject      *object,
        priv->text_column = g_value_get_int (value);
         break;
 
+      case PROP_INLINE_COMPLETION:
+       priv->inline_completion = g_value_get_boolean (value);
+        break;
+
+      case PROP_POPUP_COMPLETION:
+       priv->popup_completion = g_value_get_boolean (value);
+        break;
+
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
@@ -439,6 +520,14 @@ gtk_entry_completion_get_property (GObject    *object,
         g_value_set_int (value, gtk_entry_completion_get_text_column (completion));
         break;
 
+      case PROP_INLINE_COMPLETION:
+        g_value_set_boolean (value, gtk_entry_completion_get_inline_completion (completion));
+        break;
+
+      case PROP_POPUP_COMPLETION:
+        g_value_set_boolean (value, gtk_entry_completion_get_popup_completion (completion));
+        break;
+
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
@@ -1320,3 +1409,199 @@ gtk_entry_completion_match_selected (GtkEntryCompletion *completion,
 
   return TRUE;
 }
+
+
+static gchar *
+gtk_entry_completion_compute_prefix (GtkEntryCompletion *completion)
+{
+  GtkTreeIter iter;
+  gchar *prefix = NULL;
+  gboolean valid;
+
+  const gchar *key = gtk_entry_get_text (GTK_ENTRY (completion->priv->entry));
+
+  valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (completion->priv->filter_model),
+                                        &iter);
+  
+  while (valid)
+    {
+      gchar *text;
+      
+      gtk_tree_model_get (GTK_TREE_MODEL (completion->priv->filter_model),
+                         &iter, completion->priv->text_column, &text,
+                         -1);
+
+      if (g_str_has_prefix (text, key))
+       {
+         if (!prefix)
+           prefix = g_strdup (text);
+         else
+           {
+             gchar *p = prefix;
+             const gchar *q = text;
+             
+             while (*p && *p == *q)
+               {
+                 p++;
+                 q++;
+               }
+             
+             *p = '\0';
+           }
+       }
+      
+      g_free (text);
+      valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (completion->priv->filter_model),
+                                       &iter);
+    }
+
+  return prefix;
+}
+
+
+static gboolean
+gtk_entry_completion_real_insert_prefix (GtkEntryCompletion *completion,
+                                        gchar              *prefix)
+{
+  if (prefix)
+    {
+      gint key_len;
+      gint prefix_len;
+      gint pos;
+      const gchar *key;
+
+      prefix_len = g_utf8_strlen (prefix, -1);
+
+      key = gtk_entry_get_text (GTK_ENTRY (completion->priv->entry));
+      key_len = g_utf8_strlen (key, -1);
+
+      if (prefix_len > key_len)
+       {
+         gtk_editable_insert_text (GTK_EDITABLE (completion->priv->entry),
+                                   prefix + key_len, -1, &pos);
+         gtk_editable_select_region (GTK_EDITABLE (completion->priv->entry),
+                                     key_len, prefix_len);
+
+         completion->priv->has_completion = TRUE;
+       }
+    }
+
+  return TRUE;
+}
+
+/**
+ * gtk_entry_completion_insert_prefix:
+ * @completion: a #GtkEntryCompletion
+ * 
+ * Requests a prefix insertion. 
+ * 
+ * Since: 2.6
+ **/
+void
+gtk_entry_completion_insert_prefix (GtkEntryCompletion *completion)
+{
+  gboolean done;
+  gchar *prefix;
+
+  g_signal_handler_block (completion->priv->entry,
+                         completion->priv->insert_text_id);
+  prefix = gtk_entry_completion_compute_prefix (completion);
+  if (prefix)
+    {
+      g_signal_emit (completion, entry_completion_signals[INSERT_PREFIX],
+                    0, prefix, &done);
+      g_free (prefix);
+    }
+  g_signal_handler_unblock (completion->priv->entry,
+                           completion->priv->insert_text_id);
+}
+
+/**
+ * gtk_entry_completion_set_inline_completion:
+ * @completion: a #GtkEntryCompletion
+ * @inline_completion: %TRUE to do inline completion
+ * 
+ * Sets whether the common prefix of the possible completions should
+ * be automatically inserted in the entry.
+ * 
+ * Since: 2.6
+ **/
+void 
+gtk_entry_completion_set_inline_completion (GtkEntryCompletion *completion,
+                                           gboolean            inline_completion)
+{
+  g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
+  
+  inline_completion = inline_completion != FALSE;
+
+  if (completion->priv->inline_completion != inline_completion)
+    {
+      completion->priv->inline_completion = inline_completion;
+
+      g_object_notify (G_OBJECT (completion), "inline_completion");
+    }
+}
+
+
+/**
+ * gtk_entry_completion_get_inline_completion:
+ * @completion: a #GtkEntryCompletion
+ * 
+ * Returns whether the common prefix of the possible completions should
+ * be automatically inserted in the entry.
+ * 
+ * Return value: %TRUE if inline completion is turned on
+ * 
+ * Since: 2.6
+ **/
+gboolean
+gtk_entry_completion_get_inline_completion (GtkEntryCompletion *completion)
+{
+  g_return_val_if_fail (GTK_IS_ENTRY_COMPLETION (completion), FALSE);
+  
+  return completion->priv->inline_completion;
+}
+
+/**
+ * gtk_entry_completion_set_popup_completion:
+ * @completion: a #GtkEntryCompletion
+ * @inline_completion: %TRUE to do popup completion
+ * 
+ * Sets whether the completions should be presented in a popup window.
+ * 
+ * Since: 2.6
+ **/
+void 
+gtk_entry_completion_set_popup_completion (GtkEntryCompletion *completion,
+                                          gboolean            popup_completion)
+{
+  g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
+  
+  popup_completion = popup_completion != FALSE;
+
+  if (completion->priv->popup_completion != popup_completion)
+    {
+      completion->priv->popup_completion = popup_completion;
+
+      g_object_notify (G_OBJECT (completion), "popup_completion");
+    }
+}
+
+
+/**
+ * gtk_entry_completion_get_popup_completion:
+ * @completion: a #GtkEntryCompletion
+ * 
+ * Returns whether the completions should be presented in a popup window.
+ * 
+ * Return value: %TRUE if popup completion is turned on
+ * 
+ * Since: 2.6
+ **/
+gboolean
+gtk_entry_completion_get_popup_completion (GtkEntryCompletion *completion)
+{
+  g_return_val_if_fail (GTK_IS_ENTRY_COMPLETION (completion), TRUE);
+  
+  return completion->priv->popup_completion;
+}
index 5bdcc4c1ca5df74e6d3e53c73891b0e68d0e766a..72d00c7daf6e6e9b1cbd52d0991db3aad17bafcd 100644 (file)
@@ -63,12 +63,13 @@ struct _GtkEntryCompletionClass
                                  GtkTreeIter        *iter);
   void     (* action_activated) (GtkEntryCompletion *completion,
                                  gint                index_);
+  gboolean (* insert_prefix)    (GtkEntryCompletion *completion,
+                                gchar              *prefix); 
 
   /* Padding for future expansion */
   void (*_gtk_reserved0) (void);
   void (*_gtk_reserved1) (void);
   void (*_gtk_reserved2) (void);
-  void (*_gtk_reserved3) (void);
 };
 
 /* core */
@@ -89,6 +90,7 @@ void                gtk_entry_completion_set_minimum_key_length (GtkEntryComplet
                                                                  gint                         length);
 gint                gtk_entry_completion_get_minimum_key_length (GtkEntryCompletion          *completion);
 void                gtk_entry_completion_complete               (GtkEntryCompletion          *completion);
+void                gtk_entry_completion_insert_prefix          (GtkEntryCompletion          *completion);
 
 void                gtk_entry_completion_insert_action_text     (GtkEntryCompletion          *completion,
                                                                  gint                         index_,
@@ -99,6 +101,13 @@ void                gtk_entry_completion_insert_action_markup   (GtkEntryComplet
 void                gtk_entry_completion_delete_action          (GtkEntryCompletion          *completion,
                                                                  gint                         index_);
 
+void                gtk_entry_completion_set_inline_completion  (GtkEntryCompletion          *completion,
+                                                                 gboolean inline_completion);
+gboolean            gtk_entry_completion_get_inline_completion  (GtkEntryCompletion          *completion);
+void                gtk_entry_completion_set_popup_completion   (GtkEntryCompletion          *completion,
+                                                                 gboolean popup_completion);
+gboolean            gtk_entry_completion_get_popup_completion   (GtkEntryCompletion          *completion);
+
 /* convenience */
 void                gtk_entry_completion_set_text_column        (GtkEntryCompletion          *completion,
                                                                  gint                         column);
index aed129e027d2f8cb87206bfcbe50a743f2c0886c..7fb369b9ca2efcbd60cf5bf9a383db58b4c61091 100644 (file)
@@ -55,10 +55,14 @@ struct _GtkEntryCompletionPrivate
 
   gulong completion_timeout;
   gulong changed_id;
-  gulong key_press_id;
-  gulong key_release_id;
+  gulong insert_text_id;
 
-  gboolean ignore_enter;
+  guint ignore_enter      : 1;
+  guint has_completion    : 1;
+  guint inline_completion : 1;
+  guint popup_completion  : 1;
+
+  GSource *check_completion_idle;
 };
 
 gboolean            _gtk_entry_completion_resize_popup           (GtkEntryCompletion          *completion);